#region Imported Namespaces
using System;
using Workflow.NET;
using WorkFlowEngine = Workflow.NET.Engine;
using WorkFlowAction = Workflow.NET.ActionHandler;
using WorFlowInterface = Workflow.NET.Engine.Interfaces;
using PHSRAG.Insight21.Policy;
using System.Collections;
using InsightHumans = PHSRAG.Insight21.Humans;
using System.Threading;
using PHSRAG.Utility;
using System.Data.SqlClient;
using System.Data;
using System.Web;
using System.Configuration;
using System.Text;
#endregion

namespace PHSRAG.Insight21.InsightWorkFlow
{
    #region Class SetWorkFlowVariables
    /// <summary>
    /// This is a Skelta workflow custom action class. This class is setting Workflow variables (Example: PI User Id array - piArray
    /// Department Chair deptChairArray) for current Workflow item. IActionRun is Skelta interface to implement custom actions. 
    /// Actions.xml of particular application needs to be configured so that this action
    /// becomes accesible from Skelta Workflow Manager control under List of Actions -> Custom Actions. 	
    /// </summary>
    public class SetWorkFlowVariables : Workflow.NET.Engine.Interfaces.IActionRun
    {
        /// <summary>
        /// Default constructor
        /// </summary>
        public SetWorkFlowVariables()
        {

        }

        /// <summary>
        /// Custom action method used by Skelta Workflow engine to take certain action. This is used to set workflow variables
        /// for each Workflow item. This method gets called just before protocol gets assigned to PI and also after every submitter's
        /// accept step. This method calls HumansWorkflow assembly and gets all users for different roles assigned for particular
        /// Protocol Process. When Protocol PRoces gets submitted to Workflow all the related parameters (like Protocol Id, Protocol ProcessId)
        /// get passed to the Workflow. They get saved in the Workflow context for every item. These parameters get used to grab all users
        /// involved in the Workflow for that particular Protocol Process. All these users are saved in different arrays. These arrays get used
        /// in designing the process (E.g. In Workflow manager on PI Step "To" property of PI approval step gets configured with "UserId IN piUser" 
        /// where PIUser is an array which gets set in this method.)
        /// Submitters can change the Staff assignment that is why this step gets called from each Submitter Aceept step as well.
        /// </summary>
        /// <param name="executionId">Workflow execution Id - a unique id used for each workflow item</param>
        /// <param name="executionDetailsId">Execution detail Id - Id used for execution detail table</param>
        /// <param name="currentContext">Context class which encapsulates all the information about the executing Workflow.</param>
        /// <param name="currentAction">Current Workflow action</param>
        /// <param name="inlinkOutput">Output in string format which has come from the step before this step</param>
        /// <param name="retry">Boolean retry variable</param>
        /// <param name="output">Output value which is used by Skelta Workflow manager to takce certain path in the process.</param>
        /// <returns>The result of an action execution. Either execution is complete or action is in sleep mode.  </returns>
        public WorFlowInterface.ActionResult Run(int executionId, int executionDetailsId, WorkFlowEngine.Context currentContext, Action currentAction, string inlinkOutput, bool retry, out string output)
        {
            output = null;
            Log logger = currentContext.log;
            HumansWorkFlow humansWF = new HumansWorkFlow(new NullCachePolicy());

            try
            {
                object insightApplicationName = currentContext.Contents["insightApplicationName"];
                HumansWorkFlow.InsightApplicationName = (null == insightApplicationName) ? string.Empty : ((Content)insightApplicationName).Value.ToString();
                Thread.SetData(Thread.GetNamedDataSlot("Connections"), HumansWorkFlow.Connections);

                //set up variables for the emails in the protocols.
                currentContext.Variables["protocolTitle"].Value = String.Empty;
                currentContext.Variables["piName"].Value = String.Empty;
                currentContext.Variables["submissionType"].Value = String.Empty;
                currentContext.Variables["submitterName"].Value = String.Empty;
                currentContext.Variables["protocolProcessId"].Value = String.Empty;
                currentContext.Variables["submitterOrgName"].Value = String.Empty;
                currentContext.Variables["executionId"].Value = String.Empty;
                currentContext.Variables["comments"].Value = String.Empty;
                if (currentContext.Variables["protocolNumber"] != null)
                    currentContext.Variables["protocolNumber"].Value = String.Empty;
                if (currentContext.Variables["environment"] != null)
                    currentContext.Variables["environment"].Value = String.Empty;
                if (currentContext.Variables["environmentAddress"] != null)
                    currentContext.Variables["environmentAddress"].Value = String.Empty;
                if (currentContext.Variables["moduleType"] != null)
                    currentContext.Variables["moduleType"].Value = String.Empty;
                if (currentContext.Variables["hrorejectflag"] != null)                
                    currentContext.Variables["hrorejectflag"].Value = 0;                
                
                bool IsInterventionalStudy = false;
                string submissionType = string.Empty;
                string questionnaireType = string.Empty;
                int PIOrganizationId = 0;
                string PIOrganizationName = string.Empty;

                SqlDataReader reader = DataAccess.ExecuteReader(DataAccess.GetConnectionString(), "GetRunEnvironment");

                if (reader.Read())
                {
                    if (currentContext.Variables["environment"] != null)
                        currentContext.Variables["environment"].Value = reader["RunEnvironmentName"].ToString();
                    if (currentContext.Variables["environmentAddress"] != null)
                        currentContext.Variables["environmentAddress"].Value = reader["RunEnvironmentAddress"].ToString();                   
                }

                reader.Close();
                reader.Dispose();

                if (executionId != 0)
                {
                    currentContext.Variables["executionId"].Value = executionId;

                    reader = DataAccess.ExecuteReader(DataAccess.GetConnectionString(), 
                                                        "GetExecutionDetails", 
                                                        DataAccess.BuildSqlParameterArray("@executionId", SqlDbType.Int, executionId));

                    if (reader.Read())
                    {
                        currentContext.Variables["protocolTitle"].Value = reader["ProtocolTitle"].ToString();
                        if (currentContext.Variables["protocolNumber"] != null)
                            currentContext.Variables["protocolNumber"].Value = reader["ProtocolNumber"].ToString();
                        currentContext.Variables["piName"].Value = reader["PIName"].ToString();
                        currentContext.Variables["submissionType"].Value = reader["SubmissionType"].ToString();
                        currentContext.Variables["submitterName"].Value = reader["SubmitterName"].ToString();
                        currentContext.Variables["protocolProcessId"].Value = reader["ProtocolProcessId"].ToString();
                        currentContext.Variables["submitterOrgName"].Value = reader["SubmitterOrgName"].ToString();
                        PIOrganizationId = Int32.Parse(reader["PIOrgId"].ToString());
                        PIOrganizationName = reader["PIOrgName"].ToString();
                        IsInterventionalStudy = (reader["IsInterventionStudy"].ToString() == "1") ? true : false;
                        submissionType = reader["SubmissionType"].ToString();
                        if (currentContext.Variables["moduleType"] != null)
                            currentContext.Variables["moduleType"].Value = reader["ModuleType"].ToString();
                    }

                    reader.Close();
                    reader.Dispose();
                }
                //check if it is not SRH or IHP hospital than set to be default value of 1.
                if (!PIOrganizationName.ToString().Contains("SRH") && !PIOrganizationName.ToString().Contains("IHP") || PIOrganizationName == String.Empty)
                    PIOrganizationId = 1;                

                reader = DataAccess.ExecuteReader(DataAccess.GetConnectionString(), 
                                                   "GetQuestionnaireNameForProcess", 
                                                   DataAccess.BuildSqlParameterArray("@protocolProcessId", SqlDbType.Int, Int32.Parse(currentContext.Contents["ppid"].Value.ToString())));

                if (reader.Read())                
                    questionnaireType = reader["Name"].ToString();                

                reader.Close();
                reader.Dispose();

                //Get Submitter
                currentContext.Variables["submitterUser"].Value = humansWF.GetWorkFlowUsers(Int32.Parse(currentContext.Contents["protocolid"].Value.ToString()), Int32.Parse(currentContext.Contents["ppid"].Value.ToString()), InsightHumans.Constants.WorkflowRoleType.Submitter);

                //Get Principal Investigator						 			
                currentContext.Variables["piUser"].Value = humansWF.GetWorkFlowUsers(Int32.Parse(currentContext.Contents["protocolid"].Value.ToString()), Int32.Parse(currentContext.Contents["ppid"].Value.ToString()), InsightHumans.Constants.StaffRoleType.PrincipalInvestigator);

                //Get Department Chair 
                currentContext.Variables["deptChairUser"].Value = humansWF.GetWorkFlowUsers(Int32.Parse(currentContext.Contents["protocolid"].Value.ToString()), Int32.Parse(currentContext.Contents["ppid"].Value.ToString()), InsightHumans.Constants.WorkflowRoleType.DepartmentChair);

                //Check whether the Site PI is present	
                int hasSitePI = humansWF.IsSitePIPresent(HumansWorkFlow.GetProtocolProcessIdForWorkflowItem(executionId));
                currentContext.Variables["isSitePI"].Value = hasSitePI;

                if (hasSitePI == 1)
                {
                    //Get Site Principal Investigator					
                    currentContext.Variables["sitepiUser"].Value = humansWF.GetWorkFlowUsers(Int32.Parse(currentContext.Contents["protocolid"].Value.ToString()), Int32.Parse(currentContext.Contents["ppid"].Value.ToString()), InsightHumans.Constants.StaffRoleType.SiteResponsibleInvestigator);

                    //Get Site Department Chair					
                    currentContext.Variables["siteDeptChairUser"].Value = humansWF.GetWorkFlowUsers(Int32.Parse(currentContext.Contents["protocolid"].Value.ToString()), Int32.Parse(currentContext.Contents["ppid"].Value.ToString()), InsightHumans.Constants.WorkflowRoleType.SiteDepartmentChair);
                }

                //Get Site IRB Chair User					
                int hasSiteIRBChair = humansWF.IsSiteIRBChair(Int32.Parse(currentContext.Contents["protocolid"].Value.ToString()));
                if (hasSiteIRBChair == 1)
                    currentContext.Variables["siteIRBChairUser"].Value = humansWF.GetWorkFlowUsers(Int32.Parse(currentContext.Contents["protocolid"].Value.ToString()), Int32.Parse(currentContext.Contents["ppid"].Value.ToString()), InsightHumans.Constants.WorkflowRoleType.SiteIRBChair);

                currentContext.Variables["isSiteIRBChair"].Value = hasSiteIRBChair;

                //Get Contact people
                currentContext.Variables["contactPeopleUser"].Value = humansWF.GetContactPeople(Int32.Parse(currentContext.Contents["ppid"].Value.ToString()));

                //Get Protocol Administrator, same user as per trackit 9619
                currentContext.Variables["protocolAdministrator"].Value = humansWF.GetProtocolAdministrator(Int32.Parse(currentContext.Contents["ppid"].Value.ToString()));

                //Get HRO SignOff Person to be the same as Protocol Administrator only for nonInterventional continuing reviews.
                if (!questionnaireType.Contains("Intervention") && submissionType.Contains("CR"))
                {
                    ArrayList varHroIntakeUserList = new ArrayList();
                    varHroIntakeUserList.Add(currentContext.Variables["protocolAdministrator"].Value);
                    currentContext.Variables["hroIntakeUser"].Value = varHroIntakeUserList;
                }
                else
                    currentContext.Variables["hroIntakeUser"].Value = humansWF.GetWorkFlowUsers(Int32.Parse(currentContext.Contents["protocolid"].Value.ToString()), Int32.Parse(currentContext.Contents["ppid"].Value.ToString()), InsightHumans.Constants.WorkflowRoleType.HROIntake, PIOrganizationId);                   
                

                // Get Workflow Error Administrator
                currentContext.Variables["workflowErrorAdministrator"].Value = humansWF.GetWorkflowPeople(1, "WorkflowErrorAdmin", Int32.Parse(currentContext.Contents["ppid"].Value.ToString()));

                // Get the type of WF (init or Resub)
                // Get Ancillary board user	
                ArrayList varAnciArrayList = new ArrayList();
                if (!PIOrganizationName.ToString().Contains("SRH"))
                {
                    varAnciArrayList = humansWF.GetAncillaryBoardUsers(Int32.Parse(currentContext.Contents["protocolid"].Value.ToString()), Int32.Parse(currentContext.Contents["ppid"].Value.ToString()));
                    currentContext.Variables["anciBoardUser"].Value = varAnciArrayList;
                    //check for resubmission
                    if (varAnciArrayList != null)
                        humansWF.SetContextVariables("anciBoardUser", varAnciArrayList, Int32.Parse(currentContext.Contents["ppid"].Value.ToString()));
                }
                //Set the flag for board users. If this flag is 1 then Board approval process will be called in Workflow.
                if ((varAnciArrayList != null) && (varAnciArrayList.Count > 0))
                    currentContext.Variables["boardUsersExist"].Value = 1;
                else
                    currentContext.Variables["boardUsersExist"].Value = 0;

                //Get Non Critical Study Staff users	
                ArrayList varNCSSArrayList = new ArrayList();
                ArrayList varCSSArrayList = new ArrayList();
                int addedPIUserId = 0;
                varNCSSArrayList = humansWF.GetStudyStaffUsers(Int32.Parse(currentContext.Contents["ppid"].Value.ToString()), out varCSSArrayList, out addedPIUserId);
                currentContext.Variables["addedPIUserId"].Value = addedPIUserId;
                currentContext.Variables["cSSUsers"].Value = varCSSArrayList;

                if ((varCSSArrayList != null) && (varCSSArrayList.Count > 0))
                    currentContext.Variables["cSSUsersExist"].Value = 1;
                else
                    currentContext.Variables["cSSUsersExist"].Value = 0;

                currentContext.Variables["ncssUser"].Value = varNCSSArrayList;

                if ((varNCSSArrayList != null) && (varNCSSArrayList.Count > 0))
                    currentContext.Variables["ncssUsersExist"].Value = 1;
                else
                    currentContext.Variables["ncssUsersExist"].Value = 0;

                if (currentContext.Contents["workflowtype"].Value != null)
                    currentContext.Variables["workflowType"].Value = currentContext.Contents["workflowtype"].Value;

                currentContext.SaveVariables();
                output = "Success";
            }
            catch (Exception ex)
            {
                logger.LogMessage(ReasonConst.Error, "Unable to set workflow variables in SetWorkFlowVariables.Run() " + ex.ToString());
                output = "Failure";
            }
            finally
            {
                humansWF.Dispose();
            }
            return WorFlowInterface.ActionResult.Completed;
        }

        /// <summary>
        /// Gets the web control to be displayed in the activity list for this action. No user interface is implemented for
        /// this action. So it returns null.
        /// </summary>
        /// <returns>IActivityWebUIHandler - Interface that allows an object to implement a custom document view Control.</returns>
        public virtual Workflow.NET.Interfaces.IActivityWebUIHandler GetActivityWebUIHandler()
        {
            return null;
        }

    }
    #endregion
}
